package com.iwop.moto.controller.weixin;

import com.iwop.moto.auth.LoginAuth;
import com.iwop.moto.comm.Comm;
import com.iwop.moto.comm.ErrCode;
import com.iwop.moto.controller.BaseController;
import com.iwop.moto.model.*;
import com.iwop.moto.service.*;
import com.iwop.moto.utils.PushNoticeUtil;
import com.iwop.moto.utils.http.SessionUtils;
import com.iwop.moto.utils.http.XMLUtil;
import com.iwop.moto.utils.stringUtil.*;
import com.iwop.moto.utils.weixin.model.WxPayDto;
import com.iwop.moto.utils.weixin.utils.WxPayUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @功能: 微信支付业务模块管理
 * @创建: liuwb 2016-09-26 17:52 by
 * Create
 * @说明: 微信号[开摩邦网]支付业务模块管理
 */
@Controller
public class WxPayController extends BaseController {

    public static final String TotalFee = "0.01";//支付测试金额0.01元

    static Logger logger = Logger.getLogger(WxPayController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private MPaymentService mPaymentService;

    @Autowired
    FOrderServiceService fOrderServiceService;

    @Autowired
    private StoreService storeService;

    @Autowired
    MCouponService mCouponService;

    @Autowired
    MOrderPurchaseService mOrderPurchaseService;

    @Autowired
    MBrokerageService mBrokerageService;

    @Autowired
    private PromotionService promotionService;

    @Autowired
    MGPOrderService mgpOrderService;

    /**
     * @功能: 微信App支付
     * @参数: userId 付款方用户ID
     * @参数: outTradeNo 订单号(选填)
     * @参数: money 金额 例:0.1
     * @参数: body  商品描述
     * @参数: payType 交易类型[Service:服务订单支付][Goods:商品订单支付][Topup:充值]
     */
    @RequestMapping(value = "/api/wx/app/pay")
    @ResponseBody
    public ResultModel ApiWxAppPay(HttpServletRequest request) {
        String ctype = request.getParameter("ctype");
        SuperRecordModel req = this.getSRModel();
        SuperRecordModel params = new SuperRecordModel();
        params.put("total_fee", AmountUtils.changeY2F(req.getString("money")));
        params.put("body", JsonUtils.toJsonString(req.getString("body")));
        Map map = new HashMap<>();
        map.put("id", req.getString("userId"));
        map.put("pp", req.getString("payType"));
        if (StringUtils.isEmpty(ctype)) {
            ctype = "store";
            map.put("op", ctype);
        } else {
            map.put("op", ctype);
        }
        //map.put("to_user_id",req.getString("toUserId"));
        params.put("attach", JsonUtils.toJsonString(map));
        params.put("outTradeNo", req.getString("outTradeNo").equals("") ? SequenceUtil.Serial() : req.getString("outTradeNo"));
        SortedMap<String, String> result = null;
        if (ctype.equals("store")) {
            result = WxPayUtil.WxAppPay(params);
        } else {
            result = WxPayUtil.DYWxAppPay(params);
        }
        return getSucceed(result);
    }

    /**
     * @功能: 微信App支付（订阅号）
     * @参数: userId 付款方用户ID
     * @参数: outTradeNo 订单号
     * @参数: money 金额 例:0.1
     * @参数: body  商品描述
     * @参数: payType 交易类型[Service:服务订单支付][Goods:商品订单支付][Topup:充值]
     * @参数: coupon_id 优惠券id 用户优惠券sid
     */
    @RequestMapping(value = "/consumer/wx/app/pay")
    @ResponseBody
    public ResultModel CustomerWxAppPay(HttpServletRequest request) throws ParseException {
        String order_type = request.getParameter("ctype");
        String brokerage = request.getParameter("brokerage");
        System.out.println(brokerage);
        if (StringUtils.isEmpty(brokerage)) {
            brokerage = "0";
        }
        if (StringUtils.isEmpty(order_type)) {
            order_type = "user";
        }
        SuperRecordModel req = this.getSRModel();
        //抵用券验证
        BigDecimal money = new BigDecimal(0);
        double limitM = 0;
        if ((!StringUtils.isEmpty(req.getString("coupon_id"))) || (!StringUtils.isEmpty(req.getString("sid")))) {
            String userId = req.getString("userId");
            req.put("user_id", userId);
            SuperRecordModel superRecordModel = mCouponService.getUserCouponByCouponSid(req);
            if (superRecordModel != null && superRecordModel.size() > 0) {
                money = (BigDecimal) superRecordModel.get("money");
            }
            if (superRecordModel != null && superRecordModel.isEmpty()) {
                logger.error("用户:【" + req.get("userId").toString() + "】||【" + req.get("coupon_id").toString() + "】抵用券不存在");
                ErrorLog(null, "/consumer/wx/app/pay:抵用券不存在或系统错误", JsonUtils.toJsonString(req));
                return getErr(ErrCode.ERROR_PARAMETER);
            }
            if (superRecordModel != null && (superRecordModel.get("status_flag") == null || !superRecordModel.get("status_flag").equals("1"))) {
                ErrorLog(null, "/consumer/wx/app/pay:抵用券已使用", JsonUtils.toJsonString(req));
                logger.error(req.get("coupon_id") + ":抵用券已使用");
                return getErr(ErrCode.ERROR_PARAMETER);
            }
            if (StringUtils.isEmpty(superRecordModel.getString("limit_money"))) {
                return getErr(ErrCode.ERROR_PARAMETER);
            }
            String limit_money = superRecordModel.getString("limit_money");
            limitM = Double.parseDouble(limit_money);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-M-dd HH:mm:ss");
            String start_time = superRecordModel.get("start_time").toString();
            Date date_start_time = format.parse(start_time);
            String end_time = superRecordModel.get("end_time").toString();
            Date date_end_time = format.parse(end_time);
            if (date_start_time.getTime() > new Date().getTime() || date_end_time.getTime() < new Date().getTime()) {
                return getErr("您的优惠券不在有效时间内");
            }
        }

        String outTradeNo = req.getString("outTradeNo");
        String payOrderNo = "";
        MPayment mPayment = new MPayment();
        mPayment.setOutTradeNo(outTradeNo);
        boolean countBl = mPaymentService.findByPayTradeNoCount(mPayment);
        if (!countBl) {
            return getErr(ErrCode.ERROR_PAY);
        }
        BigDecimal bigDecimal = null;
        double parseDouble = 0;
        if (outTradeNo.contains("Ho")) {
            MGPOrder oneBySid = mgpOrderService.findOneBySid(outTradeNo);
            if (oneBySid == null) {
                return getErr(ErrCode.ERROR_SYSTEM);
            }
            bigDecimal = new BigDecimal(oneBySid.getMoney());
            payOrderNo = SequenceUtil.Serial("Ho");
            oneBySid.setPayTradeNo(payOrderNo);
            mgpOrderService.updateMGPOrder(oneBySid);
        } else {
            if (order_type.equals("user")) {
                SuperRecordModel storeOrderBySid = fOrderServiceService.getStoreOrderByOrderNo(outTradeNo);
                if (storeOrderBySid == null || storeOrderBySid.size() == 0) {
                    return getErr(ErrCode.ERROR_SYSTEM);
                }
                payOrderNo = SequenceUtil.Serial("So");
                storeOrderBySid.put("pay_order_no", payOrderNo);
                fOrderServiceService.updateStoreOrder(storeOrderBySid);
                bigDecimal = (BigDecimal) storeOrderBySid.get("money");
            } else {
                MOrderPurchase oneById = mOrderPurchaseService.findOneById(outTradeNo);
                User userBySid = userService.getUserBySid(req.getString("userId"));
                if (oneById == null) {
                    return getErr(ErrCode.ERROR_SYSTEM);
                }
                if (!StringUtils.isEmpty(brokerage)) {
                    parseDouble = Double.parseDouble(brokerage);
                    if (userBySid.getRedPacket() < parseDouble) {
                        return getErr(ErrCode.ERROR_BROKERAGE);
                    }
                }
                bigDecimal = new BigDecimal(oneById.getMoney());
                payOrderNo = SequenceUtil.Serial("Co");
                oneById.setPayOrderNo(payOrderNo);
                mOrderPurchaseService.updateOrderPurchase(oneById);
            }
        }
        //计算付款金额
        double payMoney = bigDecimal.doubleValue();
        if (limitM > 0 && limitM <= payMoney) {
            if (parseDouble > 0) {
                payMoney = bigDecimal.subtract(money).doubleValue();
            } else {
                payMoney = bigDecimal.subtract(money).doubleValue();
                payMoney = BigDecimalUtil.getSubtract(payMoney, parseDouble);
            }
        } else if (limitM > 0 && limitM > payMoney) {
            return getErr(ErrCode.ERROR_SYSTEM);
        }
        SuperRecordModel params = new SuperRecordModel();
        payMoney = BigDecimalUtil.getSubtract(payMoney, parseDouble);
        if (payMoney == 0) {
            payMoney = 0.01;
        }
        params.put("total_fee", AmountUtils.changeY2F(payMoney + ""));
        params.put("body", JsonUtils.toJsonString(req.getString("body")));
        Map map = new HashMap<>();
        map.put("id", req.getString("userId"));
        map.put("pp", req.getString("payType"));
        map.put("bo", brokerage);
        map.put("op", order_type);
        map.put("csid", req.get("sid"));
        String value = JsonUtils.toJsonString(map);
        if (StringUtils.isEmpty(payOrderNo)) {
            return getErr(ErrCode.ORDER_INFO_ERROR);
        }
        params.put("attach", value);
        params.put("outTradeNo", payOrderNo);
        SortedMap<String, String> result = null;
        if (order_type.equals("store")) {
            result = WxPayUtil.WxAppPay(params);
        } else {
            result = WxPayUtil.DYWxAppPay(params);
        }
        System.out.println("微信请求接口：" + result);
        return getSucceed(result);
    }

    /**
     * @功能: 微信支付(H5)  - 跳转 - 合伙人预定金支付
     * @日期: liuwb by 2016-10-27 15:06:53 create
     */
    @RequestMapping(value = "/api/wx/service/bargain/pay")
    @LoginAuth(isWx = true)
    public ModelAndView toServiceBargainPay() {
        ModelAndView mv = new ModelAndView();
        try {
            SuperRecordModel wxInfo = (SuperRecordModel) getSession().getAttribute(Comm.SESSION_WEIXIN_ID);
            wxInfo.put("wx_open_id", wxInfo.getString("openid"));
            wxInfo.put("user_type", "5");
            SuperRecordModel userInfo = userService.findUserByOpenId(wxInfo);
            /** 查询服务商预定金交付列表 **/
            SuperRecordModel payParams = new SuperRecordModel();
            payParams.put("pay_type", "bargain");//预定金交付金额
            payParams.put("user_id", userInfo.get("sid"));
            payParams.put("wx_open_id", userInfo.get("wx_open_id"));
            Long payCount = wxPayService.findByParamsCount(payParams);
            mv.addObject("payCount", payCount.intValue());
            mv.addObject("serviceInfo", userInfo);
            mv.setViewName("weixin/bargain");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mv;
    }

    /**
     * @功能: 微信支付(H5)  - 合伙人预定金支付
     * @日期: liuwb by 2016-10-27 15:46:18 create
     * @参数: user_id  用户id
     * @参数: total_fee 金额
     * @参数: pay_name  姓名
     * @参数: pay_tel   手机号
     */
    @RequestMapping(value = "/api/wx/h5pay/bargain")
    @LoginAuth(isWx = true)
    public ModelAndView apiWxH5payBargain() {
        ModelAndView mv = new ModelAndView();
        SuperRecordModel srmParams = this.getSRModel();//参数集
        try {
            SuperRecordModel wxInfo = (SuperRecordModel) getSession().getAttribute(Comm.SESSION_WEIXIN_ID);
            SuperRecordModel payInfo = new SuperRecordModel();
            payInfo.put("openid", wxInfo.getString("openid"));// 微信公众号用户唯一标识
            payInfo.put("out_trade_no", SequenceUtil.Serial("BN-"));
            payInfo.put("body", "开摩邦网-合伙人定金");
            Map attach = new HashMap<>();
            attach.put("user_id", srmParams.getString("user_id"));
            attach.put("pay_type", "bargain");
            payInfo.put("attach", JsonUtils.toJsonString(attach));
            payInfo.put("total_fee", srmParams.getString("total_fee"));//单位为(分)
            payInfo.put("notify_url", Comm.HTTP_URL + Comm.notifyurl);//回调函数
            SuperRecordModel srm = WxPayUtil.wxH5Pay(payInfo);
            mv.addObject("srm", srm);
            mv.setViewName("weixin/pay");
        } catch (Exception e) {
            log.error("", e);
            e.printStackTrace();
        }
        return mv;
    }

    /**
     * 微信维修店收款支付
     */
    @RequestMapping(value = "/api/wx/h5pay/store")
    @LoginAuth(isWx = true)
    public ModelAndView apiWxH5payForStore() {
        ModelAndView mv = new ModelAndView();
        SuperRecordModel srmParams = this.getSRModel();//参数集
        try {
            SuperRecordModel wxInfo = (SuperRecordModel) getSession().getAttribute(Comm.SESSION_WEIXIN_ID);
            SuperRecordModel payInfo = new SuperRecordModel();
            payInfo.put("openid", wxInfo.getString("openid"));// 微信公众号用户唯一标识
            payInfo.put("out_trade_no", SequenceUtil.Serial("BN-"));
            payInfo.put("body", "开摩邦网-合伙人定金");
            Map attach = new HashMap<>();
            attach.put("user_id", srmParams.getString("user_id"));
            attach.put("pay_type", "bargain");
            payInfo.put("attach", JsonUtils.toJsonString(attach));
            payInfo.put("total_fee", srmParams.getString("total_fee"));//单位为(分)
            payInfo.put("notify_url", Comm.HTTP_URL + Comm.notifyurl);//回调函数
            SuperRecordModel srm = WxPayUtil.wxH5Pay(payInfo);
            mv.addObject("srm", srm);
            mv.setViewName("weixin/pay");
        } catch (Exception e) {
            log.error("", e);
            e.printStackTrace();
        }
        return mv;
    }

    /**
     * @功能: APP-微信支付回调函数
     */
    @RequestMapping(value = "/wx/app/pay/callback", produces = "application/xml")
    @ResponseBody
    public String wxAppPayCallback(@RequestBody String input) throws Exception {
        System.out.println("\r\n==========================进入微信支付回调函数============================");
        System.out.println(input);
        System.out.println("=====================================END==================================\r\n");
        String xml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        try {
            Map result = XMLUtil.doXMLParse(input);
            if (result != null && result.get("transaction_id") != null && wxPayService.findPayTransactionCount(
                    result.get("transaction_id").toString()) == 0) {
                Map attach = JsonUtils.toMap(result.get("attach").toString());
              /*  boolean out_trade_no = judgeWXBack(orderType, (String) result.get("out_trade_no"));
                if(!out_trade_no){
                    return "订单信息错误";
                }*/
                double brage = getBrage(attach); //获取佣金
                SuperRecordModel wxPay = addWxPay(result, attach); //添加wxpay的表
                Double payMoney = Double.valueOf(AmountUtils.changeF2Y(wxPay.get("total_fee").toString()));
                SuperRecordModel userCoupon = new SuperRecordModel();
                if (attach.containsKey("csid") && attach.get("csid") != null) {
                    if (StringUtils.isNotEmpty(attach.get("csid").toString())) {
                        userCoupon = mCouponService.getUserCouPonBySid(attach.get("csid").toString());
                    }
                }
                MPayment mPayment = new MPayment();
                mPayment.setBrokerage(brage);
                mPayment.setPayActualMoney(payMoney);
                mPayment.setCouponId(userCoupon.getString("coupon_id"));
                String setMpaymentValue = setMpaymentValue(mPayment, wxPay, payMoney, xml, input, brage);//对mPayment对象赋值
                if (!StringUtils.isEmpty(setMpaymentValue)) {
                    return setMpaymentValue;
                }
                judgePayMoneyType(wxPay, mPayment, attach, payMoney, (String) result.get("out_trade_no"), input, brage);//判断付款类型
                mPaymentService.insert(mPayment);
//                userService.userProceeds(attach.get("id").toString(),
//                        result.get("out_trade_no").toString(),
//                        BigDecimalUtil.getAdd(mPayment.getPayFee(), mPayment.getPayMoney()));
            } else {
                ErrorLog(null, "/wx/app/pay/callback:result转换失败", input);
            }
        } catch (Exception e) {
            e.printStackTrace();
            ErrorLog(e, "/wx/app/pay/callback", input);
        }
        return xml;
    }

    public double getBrage(Map attach) {
        double brage = 0;
        if (attach.containsKey("bo")) {
            String brokerage = (String) attach.get("bo");
            brage = Double.parseDouble(brokerage);
        }
        return brage;
    }
//
//    /**
//     *判断订单是否从微信回调
//     * */
//    private boolean judgeWXBack(String orderType,String out_trade_no){
//        Map<Object, String> param = WxPayUtil.getUserWxOrderInfo(out_trade_no, orderType);
//        return param.get("return_code").equals("SUCCESS");
//    }

    /**
     * 判断付款类型
     */
    private void judgePayMoneyType(Map wxPay, MPayment mPayment, Map attach, double payMoney, String out_trade_no, String input, double brage) {
        if (wxPay.get("pay_type").toString().equals("Topup")) {
            mPayment.setOutTradeNo(out_trade_no);
            mPayment.setPayTime(new Date());
            addTopup(mPayment);//添加充值
        } else if (wxPay.get("pay_type").toString().equals("Service")) {//服务订单支付
            judgeCoupon(attach, mPayment, out_trade_no);//判断是否有优惠券
            User storeUser = judgeOrderType(attach, wxPay, mPayment);//判断推送付款类型
            Double payFee = mPayment.getPayFee();
            Double payMoney1 = mPayment.getPayMoney();
            double money = BigDecimalUtil.getAdd(payFee, payMoney1);
            addBrokerage(wxPay, money, mPayment.getOutTradeNo());//获取佣金
            addUserMoney(mPayment, storeUser, brage);//更新用户钱包
        } else {
            ErrorLog(null, "/wx/pay/callback:交易类型不存在", input);
        }
    }


    /**
     * 更新用户钱包
     */
    private void addUserMoney(MPayment mPayment, User storeUser, double brage) {
        mPayment.setOriginalTmoney(storeUser.getRmoney());//用户操作前金额
        double lastMoney = BigDecimalUtil.getAdd(storeUser.getRmoney(), mPayment.getPayMoney());
        storeUser.setRmoney(BigDecimalUtil.getAdd(lastMoney, brage));//用户操作成功后金额
        mPayment.setModifyTmoney(BigDecimalUtil.getAdd(storeUser.getRmoney(), brage));//用户修改后金额
        if (brage > 0) {
            User user = userService.getUserBySid(mPayment.getBuyerUserId());
            if (user.getRedPacket() > brage) {
                user.setRedPacket(BigDecimalUtil.getSubtract(user.getRedPacket(), brage));
            } else {
                user.setRedPacket(0);
            }
            userService.updateRedPacketBySid(user);
        }
        userService.updateUserRmoneyBySid(storeUser);
        mPayment.setSellerUserId(storeUser.getSid());//开摩邦用户id(卖家/收款方)
        PushNoticeUtil.sendPersonNotice("您有一笔订单已付款成功!", "store", storeUser.getSid());
    }

    /**
     * 判断是否有优惠券
     */
    private void judgeCoupon(Map attach, MPayment mPayment, String out_trade_no) {
        if (attach.containsKey("csid") && (!StringUtils.isEmpty((String) attach.get("csid")))) {
            managerCoupon(mPayment, attach, out_trade_no);//优惠券处理
        } else {
            double brokerage = BigDecimalUtil.getMultiply(mPayment.getPayMoney(), Comm.BROKERAGE);
            double afterPayMoney = BigDecimalUtil.getSubtract(mPayment.getPayMoney(), brokerage);//手续费后的金额
            mPayment.setPayMoney(afterPayMoney);//分转元
            mPayment.setPayFee(brokerage);
        }
    }

    /**
     * 添加MPayment对象
     */
    private String setMpaymentValue(MPayment mPayment, Map wxPay, double payMoney, String xml, String input, double brage) {
        mPayment.setPayId(ObjectId.UUID());
        mPayment.setBuyerUserId(wxPay.get("user_id") == null ? null : wxPay.get("user_id").toString());
        mPayment.setMchType("WXPAY");
        mPayment.setMchId(wxPay.get("mch_id") == null ? null : wxPay.get("mch_id").toString());
        mPayment.setPayTradeNo(wxPay.get("transaction_id") == null ? null : wxPay.get("transaction_id").toString());
        boolean countBl = mPaymentService.findByPayTradeNoCount(mPayment);
        if (countBl == false) {/** 判断微信的回调订单号是否处理过 避免重复金额错误 **/
            ErrorLog(null, "/wx/app/pay/callback:微信支付重复订单回调", input);
            return xml;
        }
        //  mPayment.setPayMoney(BigDecimalUtil.getAdd(brage, payMoney));
        mPayment.setPayMoney(payMoney);
        mPayment.setPayStatus("1");
        mPayment.setPayTime(new Date());
        mPayment.setPayType(wxPay.get("pay_type") == null ? null : wxPay.get("pay_type").toString());
        return "";
    }

    /**
     * 添加微信wxPay表
     */
    private SuperRecordModel addWxPay(Map result, Map attach) {
        SuperRecordModel wxPay = new SuperRecordModel();
        wxPay.put("sid", ObjectId.UUID());
        wxPay.put("user_id", attach.get("id"));
        //wxPay.put("to_user_id", result.get("to_user_id"));
        wxPay.put("pay_type", attach.get("pp"));
        wxPay.put("transaction_id", result.get("transaction_id"));
        wxPay.put("total_fee", result.get("total_fee"));
        wxPay.put("out_trade_no", result.get("out_trade_no"));
        wxPay.put("mch_id", result.get("mch_id"));
        wxPay.put("pay_time", new Date());
        // wxPay.put("cid", attach.get("cid"));
        wxPayService.insert(wxPay);
        return wxPay;
    }

    /**
     * 添加充值
     */
    private void addTopup(MPayment mPayment) {
        mPayment.setSellerUserId(mPayment.getBuyerUserId());
        User user = userService.getUserBySid(mPayment.getBuyerUserId());
        mPayment.setOriginalTmoney(user.getRmoney());//用户操作前金额
        user.setRmoney(user.getRmoney() + mPayment.getPayMoney());//用户操作成功后金额
        mPayment.setModifyTmoney(user.getRmoney());
        userService.updateUserRmoneyBySid(user);
    }

    /**
     * 优惠券处理
     */
    private void managerCoupon(MPayment mPayment, Map attach, String out_trade_no) {
        SuperRecordModel superRecordModel = new SuperRecordModel();
        superRecordModel.put("coupon_id", attach.get("cid"));
        superRecordModel.put("user_id", attach.get("id"));
        superRecordModel.put("sid", attach.get("csid"));
        SuperRecordModel srm = mCouponService.findUserCouponBySidAndUserId(superRecordModel);
        superRecordModel.put("coupon_id", srm.get("coupon_id"));
        SuperRecordModel thisUsercoupon = mCouponService.getUserCouponByCouponIdAndUserId(superRecordModel);

        mPayment.setCouponId(srm.getString("coupon_id"));
        srm.put("status_flag", "2");
        srm.put("status_time", new Date());
        mCouponService.updateUserCouponStatusBySid(srm);
        if (srm != null) {
            BigDecimal money = (BigDecimal) thisUsercoupon.get("money");//抵用金额
            String limit_money = thisUsercoupon.getString("limit_money");
            double limitMoney = Double.parseDouble(limit_money);
            double sourceMoney = BigDecimalUtil.getAdd(mPayment.getPayMoney(), money.doubleValue());//原始交易金额
            if (sourceMoney < limitMoney) {
                logger.error("抵用券金额出现错误，错误抵用券id：" + attach.get("cid") + " 订单id：" + out_trade_no);
            }
            double brokerage = BigDecimalUtil.getMultiply(sourceMoney, Comm.BROKERAGE);
            double afterPayMoney = BigDecimalUtil.getSubtract(sourceMoney, brokerage);//手续费后的金额
            mPayment.setPayMoney(afterPayMoney);//分转元
            mPayment.setPayFee(brokerage);
        }
    }

    /**
     * 判断是推送付款订单，采购订单
     */
    private User judgeOrderType(Map attach, Map wxPay, MPayment mPayment) {
        User storeUser = new User();
        String orderType = (String) attach.get("op");
        String out_trade_no = (String) wxPay.get("out_trade_no");
        if (!out_trade_no.contains("Ho")) {
            if (orderType.equals("user")) {
                SuperRecordModel service = new SuperRecordModel();
                service = fOrderServiceService.getStoreOrderByPayOrderNo(out_trade_no);
                mPayment.setOutTradeNo(service.getString("orderno"));
                service.put("pushstatus", "1");//支付成功
                fOrderServiceService.updateStoreOrderStatus(service);
                SuperRecordModel store = null;
                try {
                    store = storeService.getStoreBySid(service.get("store_id").toString());
                } catch (Exception e) {
                    ErrorLog(e, service.get("store_id").toString() + "维修店未找到");
                    e.printStackTrace();
                }
                storeUser = userService.getUserBySid(store.get("user_id").toString());
            } else {
                MOrderPurchase mOrderPurchase = mOrderPurchaseService.findOneByPayOrderNo(out_trade_no);
                mOrderPurchase.setStatus(1);
                mOrderPurchase.setPrize(1);
                mPayment.setOutTradeNo(mOrderPurchase.getSid());
                mOrderPurchaseService.updateOrderPurchase(mOrderPurchase);
                SuperRecordModel store = storeService.getStoreBySid(mOrderPurchase.getSellerStoreId());
                storeUser = userService.getUserBySid(store.get("user_id").toString());
            }
        } else {
            MGPOrder mgpOrder = mgpOrderService.findGPOrderByPayOutTradeNo(out_trade_no);
            mPayment.setOutTradeNo(mgpOrder.getOrderNo());
            mPayment.setPayType("TRANSFER");
            mgpOrder.setStatusFlag("1");
            mPayment.setContent(mgpOrder.getContent());
            mgpOrderService.updateMGPOrder(mgpOrder);
            SuperRecordModel store = storeService.getStoreBySid(mgpOrder.getStoreId());
            storeUser = userService.getUserBySid(store.get("user_id").toString());
        }
        return storeUser;
    }

    /**
     * 添加佣金
     */
    public void addBrokerage(Map wxPay, double moneys, String outTradeNo) {
        if (moneys > 5) {
            String user_id = (String) wxPay.get("user_id");
            String keyName = user_id + "_new";
            String valueFromSession = (String) SessionUtils.getValueFromSession(keyName);
            if (!StringUtils.isEmpty(valueFromSession)) {
                if (valueFromSession.equals("new")) {
                    String hostUserInfo = promotionService.findHostUserById(user_id);
                    int count = promotionService.countFromUserByHostId(hostUserInfo);
                    double money = getBrokerage(count);
                    if (!StringUtils.isEmpty(hostUserInfo)) {
                        User userBySid = userService.getUserBySid(hostUserInfo);
                        if (userBySid != null) {
                            MBrokerage mBrokerage = new MBrokerage();
                            mBrokerage.setSid(ObjectId.UUID());
                            mBrokerage.setSellerUserId(userBySid.getSid());
                            mBrokerage.setBuyerUserId(user_id);
                            mBrokerage.setOriginalTmoney(userBySid.getRedPacket());
                            double modifyTmoney = userBySid.getRedPacket() + money;
                            mBrokerage.setModifyTmoney(modifyTmoney);
                            mBrokerage.setPayMoney(money);
                            mBrokerage.setPayStatus("1");
                            mBrokerage.setPayType("WXPAY");
                            mBrokerage.setPayTime(new Date());
                            mBrokerage.setOutTradeNo(outTradeNo);
                            mBrokerageService.insert(mBrokerage);
                            userBySid.setRedPacket(modifyTmoney);
                            userBySid.setNewUser("old");
                            userService.updateRedPacketBySid(userBySid);
                            SessionUtils.setKeyValue(keyName, "old");
                            User userBySid1 = userService.getUserBySid(user_id);
                            userBySid1.setNewUser("old");
                            userService.updateRedPacketBySid(userBySid1);
                        }
                    }
                }
            }
        }
    }

    private double getBrokerage(int people) {
        if (people < 19) {
            return 4;
        } else if (people < 99) {
            return 5;
        } else {
            return 6;
        }
    }

    /**
     * 微信维修店收款支付
     */
    @RequestMapping(value = "api/wx/h5pay/gporder")
    @LoginAuth(isWx = true)
    public ModelAndView WXH5Pay(HttpServletRequest request) {
        ModelAndView mv = new ModelAndView();
        try {
            String out_trade_no = request.getParameter("out_trade_no");
            MGPOrder oneBySid = mgpOrderService.findOneBySid(out_trade_no);
            Double money = oneBySid.getMoney();
            String store_id = oneBySid.getStoreId();
            SuperRecordModel wxInfo = (SuperRecordModel) getSession().getAttribute(Comm.SESSION_WEIXIN_ID);
            SuperRecordModel payInfo = new SuperRecordModel();
            payInfo.put("openid", wxInfo.getString("openid"));// 微信公众号用户唯一标识
            payInfo.put("out_trade_no", out_trade_no);
            payInfo.put("body", "开摩邦网-扫码支付");
            Map attach = new HashMap<>();
            attach.put("store_id", store_id);
            attach.put("pay_type", "WXPAY");
            attach.put("money", money + "");
            attach.put("name", wxInfo.getString("nickname"));
            payInfo.put("attach", JsonUtils.toJsonString(attach));
            payInfo.put("total_fee", AmountUtils.changeY2F(money + ""));//单位为(分)
            payInfo.put("notify_url", Comm.HTTP_URL + Comm.notifyurl);//回调函数
            SuperRecordModel srm = WxPayUtil.wxH5Pay(payInfo);
            mv.addObject("srm", srm);
            mv.setViewName("weixin/pay");
        } catch (Exception e) {
            log.error("微信扫码支付失败：", e);
            e.printStackTrace();
        }
        return mv;
    }

    /**
     * @param input
     * @功能: 微信扫码/公众号支付成功的回调函数
     * @说明: 配置路径:WxPayUtil notifyurl = "http://15558f1v51.imwork.net/wx/pay/callback";
     */
    @RequestMapping(value = "/wx/pay/callback", produces = "application/xml")
    @ResponseBody
    public String wxPayCallback(@RequestBody String input) throws Exception {
        System.out.println("\r\n==========================进入微信支付回调函数============================");
        System.out.println(input);
        System.out.println("=====================================END==================================\r\n");
        try {
            Map result = XMLUtil.doXMLParse(input);
            if (result != null && result.get("transaction_id") != null && wxPayService.findPayTransactionCount(
                    result.get("transaction_id").toString()) == 0) {
            }

            if (result != null && result.get("transaction_id") != null && wxPayService.findPayTransactionCount(
                    result.get("transaction_id").toString()) == 0) {
                Map attach = JsonUtils.toMap(result.get("attach").toString());
                SuperRecordModel wxPay = new SuperRecordModel();
                wxPay.put("sid", ObjectId.UUID());
                wxPay.put("user_id", attach.get("user_id"));
                String openid = (String) result.get("openid");
                wxPay.put("wx_open_id", openid);
                wxPay.put("pay_type", attach.get("pay_type"));
                wxPay.put("transaction_id", result.get("transaction_id"));
                wxPay.put("total_fee", result.get("total_fee"));
                wxPay.put("out_trade_no", result.get("out_trade_no"));
                wxPay.put("mch_id", result.get("mch_id"));
                wxPay.put("pay_time", new Date());
                wxPayService.insert(wxPay);

                String total_fee = (String) attach.get("money");
                String store_id = (String) attach.get("store_id");
                String out_trade_no = (String) result.get("out_trade_no");
                String name = (String) attach.get("name");
                double payMoney = Double.parseDouble(total_fee);
                MPayment payment = new MPayment();
                payment.setPayId(ObjectId.UUID());
                payment.setPayBuyerId(name);
                payment.setBuyerUserId(name);//开摩邦用户id(买家/付款方)
                payment.setMchId((String) result.get("mch_id"));
                payment.setOutTradeNo((String) result.get("out_trade_no"));
                payment.setPayTradeNo((String) result.get("trade_no"));
                payment.setPayActualMoney(payMoney);
                payment.setPayType("TRANSFER");
                payment.setMchType("WXPAY");
                payment.setPayTime(new Date());// 交易时间
                payment.setPayDescribe(result.get("subject") == null ? "" : (String) result.get("subject"));
                double brokerage = BigDecimalUtil.getMultiply(payMoney, Comm.BROKERAGE);//平台服务费
                payment.setPayFee(brokerage);//服务费
                double subtract = BigDecimalUtil.getSubtract(payMoney, brokerage);
                payment.setPayMoney(subtract);

                boolean countBl = mPaymentService.findByPayTradeNoCount(payment);
                if (countBl == false) {/** 判断微信的回调订单号是否处理过 避免重复金额错误 **/
                    ErrorLog(null, "/wx/pay/callback:微信支付重复订单回调", input);
                    return input;
                }

                SuperRecordModel storeBySid = storeService.getStoreBySid(store_id);
                String userId = storeBySid.getString("user_id");
                User user = userService.getUserBySid(userId);
                Double rmoney = user.getRmoney();
                payment.setOriginalTmoney(rmoney);
                double addMoney = BigDecimalUtil.getAdd(rmoney, payment.getPayMoney());
                payment.setModifyTmoney(addMoney);//用户修改后金额
                user.setRmoney(addMoney);
                userService.updateUserRmoneyBySid(user);
                MGPOrder mgpOrder = mgpOrderService.findOneBySid(out_trade_no);
                mgpOrder.setUserId(name);
                mgpOrder.setStatusFlag("1");
                mgpOrder.setStatusTime(new Date());
                mgpOrderService.updateMGPOrder(mgpOrder);
                payment.setSellerUserId(user.getSid());
                payment.setContent(mgpOrder.getContent());
                payment.setPayStatus("1");
                mPaymentService.insert(payment);

            } else {
                ErrorLog(null, "/wx/pay/callback:result转换失败", JsonUtils.toJsonString(input));
            }
        } catch (Exception e) {
            e.printStackTrace();
            ErrorLog(e, "/wx/pay/callback", JsonUtils.toJsonString(input));
        }
        String xml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        return xml;
    }

    /**
     * @功能: 查看用户微信支付信息
     * @日期: liuwb by 2016-10-31 10:49:53 create
     * @参数: user_id  用户Id
     * @参数: pay_type 交易类型
     */
    @RequestMapping(value = "/api/wx/pay/history")
    @LoginAuth(isWx = true)
    public ModelAndView apiWxPayHistory() {
        ModelAndView mv = new ModelAndView();
        SuperRecordModel srmParams = this.getSRModel();
        List<SuperRecordModel> srmLs = wxPayService.findByParams(srmParams);
        mv.addObject("srmLs", srmLs);
        mv.setViewName("weixin/pay_history");
        return mv;
    }


    /**
     * @功能: 微信扫码支付测试
     * @日期: liuwb by 2016-10-10 09:08:33
     */
    @RequestMapping(value = "/wx/pay/scan/code")
    @ResponseBody
    public ResultModel getWxScanCode() throws Exception {
        SuperRecordModel pd = new SuperRecordModel();
        WxPayDto tpWxPay = new WxPayDto();
        String encoderImgId = SequenceUtil.Serial("MOBOM-");//订单号/二维码图片名称
        tpWxPay.setBody("测试");
        tpWxPay.setOrderId(encoderImgId);
        tpWxPay.setSpbillCreateIp("127.0.0.1");
        tpWxPay.setTotalFee(TotalFee);//测试金额0.01元
        tpWxPay.setNotifyUrl(Comm.HTTP_URL + Comm.notifyurl);//回调函数地址
        String barCodeUrl = WxPayUtil.getCodeurl(tpWxPay);//发送请求
        pd.put("result", "success"); //返回结果
        pd.put("qrcodeUrl", barCodeUrl); //支付链接
        return getSucceed(pd);
    }


    /**
     * @功能: 微信支付(H5)
     * @日期: liuwb 2016-10-10 15:03:58
     * @说明: url地址  服务器地址 + /api/wx/h5pay/test 需要在商户号配置路径至【服务器地址 + /api/wx/h5pay/】配置至最后一级的前一个斜杠
     */
    @RequestMapping(value = "/api/wx/h5pay/test")
    @LoginAuth(isWx = true)
    public ModelAndView apiWxH5payTest() {
        ModelAndView mv = new ModelAndView();
        SuperRecordModel srmParams = this.getSRModel();
        try {
            String out_trade_no = SequenceUtil.Serial("M");//业务
            SuperRecordModel wxInfo = (SuperRecordModel) getSession().getAttribute(Comm.SESSION_WEIXIN_ID);
            srmParams.put("openid", wxInfo.getString("openid"));
            srmParams.put("out_trade_no", out_trade_no);
            srmParams.put("body", "开摩邦-交易描述");
            srmParams.put("attach", "附加数据:原样返回回调函数的");
            srmParams.put("total_fee", "1");//单位为(分)
            srmParams.put("notify_url", Comm.HTTP_URL + Comm.notifyurl);//回调函数
            SuperRecordModel srm = WxPayUtil.wxH5Pay(srmParams);
            mv.addObject("srm", srm);
            mv.setViewName("weixin/pay");
        } catch (Exception e) {
            log.error("", e);
            e.printStackTrace();
        }
        return mv;
    }

/*    @RequestMapping(value = "/api/wx/h5pay/test")
    @LoginAuth(isWx = true)
    public ResultModel updateMpayent() {

        return getSucceed(ErrCode.SUCCEED);
    }*/
}
